package webapp.mvc.controllers;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Function;
import com.zoowii.formutils.BindingResult;
import com.zoowii.formutils.Validator;
import com.zoowii.jpa_utils.extension.Paginator;
import com.zoowii.jpa_utils.util.ListUtil;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import webapp.mvc.components.HttpManager;
import webapp.mvc.controllers.forms.*;
import webapp.mvc.exceptions.ShopException;
import webapp.mvc.exceptions.UserException;
import webapp.mvc.models.*;
import webapp.mvc.services.ICategoryService;
import webapp.mvc.services.IShopService;
import webapp.mvc.services.ISiteConfigService;
import webapp.mvc.utils.HttpUtil;
import webapp.mvc.utils.NumberUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Controller
@RequestMapping("/shop")
public class ShopController {

    private static final Logger LOG = LoggerFactory.getLogger(ShopController.class);

    @Autowired
    private Validator validator;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private HttpManager httpManager;
    @Autowired
    private ISiteConfigService siteConfigService;

    @RequestMapping("/list")
    public @ResponseBody
    String listShops(HttpServletRequest request) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
//        paginator.setPageSize(10);
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("createTime", false));
        String categoryId = request.getParameter("category");
        List<ShopEntity> shopEntities = shopService.getShops(categoryId, paginator);
        ListUtil.map(shopEntities, new Function<ShopEntity, Object>() {
            @Override
            public Object apply(ShopEntity shopEntity) {
                shopEntity.setCategory(categoryService.findById(shopEntity.getCategoryId()));
                return null;
            }
        });
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", shopEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }

    @RequestMapping("/list_changes")
    public
    @ResponseBody
    String listShopChanges(HttpServletRequest request) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
//        paginator.setPageSize(10);
        paginator.getOrders().add(Pair.of("createTime", false));
        List<ShopChangeRequestEntity> shopChangeRequestEntities = shopService.getShopChangeRequests(paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", shopChangeRequestEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }

    @RequestMapping(value = "/agree_shop_change/{id}", method = RequestMethod.POST)
    public
    @ResponseBody
    String agreeShopChange(@PathVariable String id) {
        ShopEntity shopEntity = shopService.agreeShopChangeRequest(id);
        return SimpleResponse.ok(shopEntity).toJSON();
    }

    @RequestMapping(value = "/disagree_shop_change/{id}", method = RequestMethod.POST)
    public
    @ResponseBody
    String disagreeShopChange(@PathVariable String id) {
        ShopChangeRequestEntity shopChangeRequestEntity = shopService.disagreeShopChangeRequest(id);
        return SimpleResponse.ok(shopChangeRequestEntity).toJSON();
    }

    @RequestMapping(value = "/search", method = {RequestMethod.GET, RequestMethod.POST})
    public
    @ResponseBody
    String searchShops(HttpServletRequest request) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("createTime", false));
        String keyword = request.getParameter("keyword");
        List<ShopEntity> shopEntities = shopService.searchShops(keyword, paginator);
        ListUtil.map(shopEntities, new Function<ShopEntity, Object>() {
            @Override
            public Object apply(ShopEntity shopEntity) {
                shopEntity.setCategory(categoryService.findById(shopEntity.getCategoryId()));
                return null;
            }
        });
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", shopEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }

    @RequestMapping("/hotest")
    public
    @ResponseBody
    String getHotestShops(HttpServletRequest request) {
        int indexHotestShopsCountConfig = NumberUtils.tryParseInt(siteConfigService.get("index_hotest_shops_count"));
        if (indexHotestShopsCountConfig < 1) {
            indexHotestShopsCountConfig = 5;
        }
        int limit = HttpUtil.getIntRequestParam(request, "limit", indexHotestShopsCountConfig);
        List<ShopEntity> shopEntities = shopService.getHotestShops(limit);
        return SimpleResponse.ok(shopEntities).toJSON();
    }

    @RequestMapping("/my_shops")
    public
    @ResponseBody
    String getMyShops(HttpServletRequest request) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        List<ShopEntity> shopEntities = shopService.getShopsOwnedByUser(userEntity.getId());
        shopService.setShopsRelated(shopEntities);
        return SimpleResponse.ok(shopEntities).toJSON();
    }

    @RequestMapping("/comments/{shopId}")
    public
    @ResponseBody
    String getShopComments(HttpServletRequest request, @PathVariable String shopId) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 50));
        paginator.getOrders().add(Pair.of("createTime", false));
        List<ShopCommentEntity> commentEntities = shopService.getShopComments(shopId, paginator);
        if(request.getParameter("page")!=null) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("records", commentEntities);
            jsonObject.put("total", paginator.getTotal());
            return SimpleResponse.ok(jsonObject).toJSON();
        }
        return SimpleResponse.ok(commentEntities).toJSON();
    }
    
    @RequestMapping(value = "/delete_comments", method = RequestMethod.POST)
    public 
    @ResponseBody
    String deleteShopComments(HttpServletRequest request) {
        String idsStr = request.getParameter("ids");
        List<String> ids = Arrays.asList(idsStr.split(","));
        shopService.deleteShopComments(ids);
        return SimpleResponse.ok(true).toJSON();
    }

    @RequestMapping(value = "/add_comment", method = RequestMethod.POST)
    public
    @ResponseBody
    String addShopComment(HttpServletRequest request, CreateShopCommentForm createShopCommentForm) {
        BindingResult bindingResult = validator.validate(createShopCommentForm);
        if (bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail("尚未登录").toJSON();
        }
        try {
            ShopCommentEntity commentEntity = shopService.createShopComment(userEntity.getId(), createShopCommentForm.getShopId(), createShopCommentForm.getTitle(), createShopCommentForm.getContent());
            return SimpleResponse.ok(commentEntity).toJSON();
        } catch (ShopException e) {
            LOG.error("create product comment error", e);
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public @ResponseBody
    String createShop(HttpServletRequest request, CreateShopForm createShopForm) {
        BindingResult bindingResult = validator.validate(createShopForm);
        if(bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        try {
            ShopEntity shopEntity = shopService.createShop(userEntity.getId(), createShopForm);
            return SimpleResponse.ok(shopEntity).toJSON();
        } catch (ShopException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }
    @RequestMapping(value = "/update/{shopId}", method = RequestMethod.POST)
    public @ResponseBody
    String updateShop(HttpServletRequest request, @PathVariable String shopId, UpdateShopForm updateShopForm) {
        BindingResult bindingResult = validator.validate(updateShopForm);
        if(bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        try {
            ShopEntity shopEntity = shopService.updateShop(userEntity.getId(), shopId, updateShopForm);
            return SimpleResponse.ok(shopEntity).toJSON();
        } catch (ShopException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }
    
    @RequestMapping("/info/{shopId}")
    public @ResponseBody String getShop(@PathVariable String shopId) {
        ShopEntity shopEntity = shopService.findById(shopId);
        if(shopEntity == null) {
            return SimpleResponse.fail("找不到商户" + shopId).toJSON();
        }
        return SimpleResponse.ok(shopEntity).toJSON();
    }

    @RequestMapping(value = "/collect/{shopId}", method = RequestMethod.POST)
    public @ResponseBody
    String collectShop(HttpServletRequest request, @PathVariable String shopId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        shopService.collectShop(shopId, userEntity.getId());
        return SimpleResponse.ok("done").toJSON();
    }

    @RequestMapping(value = "/uncollect/{shopId}", method = RequestMethod.POST)
    public @ResponseBody
    String unCollectShop(HttpServletRequest request, @PathVariable String shopId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        shopService.unCollectShop(shopId, userEntity.getId());
        return SimpleResponse.ok("done").toJSON();
    }

    @RequestMapping(value = "/has_collected/{shopId}", method = RequestMethod.POST)
    public @ResponseBody
    String hasCollected(HttpServletRequest request, @PathVariable String shopId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        boolean hasCollected = shopService.isCollectedShop(shopId, userEntity.getId());
        return SimpleResponse.ok(hasCollected).toJSON();
    }

    @RequestMapping("/user_collected/{userId}")
    public @ResponseBody
    String getUserCollectedShops(HttpServletRequest request, @PathVariable String userId) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
        paginator.setPageSize(10);
        List<ShopEntity> productEntities = shopService.getUserCollectedShops(userId, paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", productEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }
    
    @RequestMapping(value = "/create_feedback", method = RequestMethod.POST)
    public @ResponseBody
    String createShopFeedback(HttpServletRequest request, CreateShopFeedbackForm createShopFeedbackForm) {
        BindingResult bindingResult = validator.validate(createShopFeedbackForm);
        if(bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        try {
            ShopFeedbackEntity shopFeedbackEntity = shopService.createShopFeedback(userEntity.getId(),
                    createShopFeedbackForm.getShopId(), createShopFeedbackForm);
            return SimpleResponse.ok(shopFeedbackEntity).toJSON();
        } catch (ShopException e) {
            LOG.error("create shop feed back error");
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }
    
    @RequestMapping("/feedbacks/{shopId}")
    public @ResponseBody
    String getShopFeedbacks(HttpServletRequest request, @PathVariable String shopId) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
        paginator.setPageSize(10);
        List<ShopFeedbackEntity> shopFeedbackEntities = shopService.getShopFeedbacks(shopId, paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", shopFeedbackEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }
}
